/*
 * Copyright (C) 2010-2011 Comcast Cable.  All Rights Reserved.
 */
package com.hercules.android.receiver.handlers.commands;

import com.hercules.android.receiver.AndroidReceiver;
import com.hercules.android.receiver.AndroidReceiverException;
import com.hercules.android.receiver.LogUtil;
import com.hercules.android.receiver.handlers.commands.CommandHandlersUtil.ValidationException;
import com.hercules.android.receiver.model.commands.XRECommand;
import com.hercules.android.receiver.model.commands.XREShutdownCommand;
import com.hercules.android.receiver.painting.XREObjectPainter;
import com.hercules.android.receiver.painting.XREObjectPainterException;

/**
 * The handler used to process XREShutdownCommand. It will shut down the receiver. It extends XRECommandHandler for
 * convenience.
 * <p>
 * <b>Sample Usage:</b> Please look at sample usage of {@link XREAggregateCommandHandler}.
 * <p>
 * <b>Thread Safety:</b> This class is not thread safe since it has mutable fields. But if they are not changed after
 * first configured, then this class is used in a thread safe manner.
 *
 * @author liuliquan, 7realm
 * @version 1.0
 */
public class XREShutdownCommandHandler extends XRECommandHandler {
    /**
     * The painter used to perform technology specific cleanup.
     * <p>
     * Initial value is null. Can be any value. If it is null then no cleanup will be performed. It has getter and
     * setter.
     */
    private XREObjectPainter applicationPainter;

    /**
     * Default empty constructor.
     */
    public XREShutdownCommandHandler() {
        // empty
    }

    /**
     * Handle given SHUTDOWN command message.
     *
     * @param command the XRE SHUTDOWN command to be handled
     * @param receiver the receiver for the XRE application
     * @throws IllegalArgumentException if given command or receiver is null
     * @throws XRECommandHandlerException if any error occurs while handling the command
     */
    @Override
    protected void processCommandMessage(XRECommand command, AndroidReceiver receiver)
        throws XRECommandHandlerException {
        String methodName = "processCommandMessage";
        LogUtil.enter(getLogger(), this, methodName, command, receiver);

        try {
            // check arguments
            CommandHandlersUtil.checkCommand(command, XREShutdownCommand.class);
            CommandHandlersUtil.checkReceiver(receiver);

            LogUtil.info(getLogger(), this, methodName, "Shutting down receiver for {0}", receiver
                .getApplicationConnectData().getUrl());

            CommandHandlersUtil.paintRootView(command, receiver, applicationPainter);

            // shut down the receiver
            receiver.doShutdown(false);
            LogUtil.exit(getLogger(), this, methodName);
        } catch (IllegalArgumentException e) {
            throw LogUtil.error(getLogger(), this, methodName, e);
        } catch (XRECommandHandlerException e) {
            throw LogUtil.error(getLogger(), this, methodName, e);
        } catch (ValidationException e) {
            throw LogUtil.error(getLogger(), this, methodName, new XRECommandHandlerException(e.getMessage(), e));
        } catch (XREObjectPainterException e) {
            throw LogUtil.error(getLogger(), this, methodName, new XRECommandHandlerException(
                "Error occurred while painting root XRE view with application painter.", e));
        } catch (AndroidReceiverException e) {
            throw LogUtil.error(getLogger(), this, methodName, new XRECommandHandlerException(
                "Error occurred while shutting receiver down.", e));
        }
    }

    /**
     * Gets the painter used to perform technology specific cleanup.
     *
     * @return the painter used to perform technology specific cleanup
     */
    public XREObjectPainter getApplicationPainter() {
        return applicationPainter;
    }

    /**
     * Sets the painter used to perform technology specific cleanup.
     *
     * @param applicationPainter the painter used to perform technology specific cleanup
     */
    public void setApplicationPainter(XREObjectPainter applicationPainter) {
        this.applicationPainter = applicationPainter;
    }
}